package StreamStudy.Exa04;

import ReflectStudy.util.ProxyTest;


import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 流的终结：从流中获取结果集
 * 涉及的API:count,max,min,collect,findFirst,findAny,anyMatch,allMatch,noneMatch
 */
public class StreamEnd {

    private static final String[] words = {"hello", "world", "change", "self", "result","result"};


    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        String function = "nonMatch";
        testProxy(function);

    }


    /**
     * 测试代理类,根据名称路由到具体的方法执行
     * @param functionName
     */
    public static void testProxy(String functionName)
            throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        System.out.println("words 内容入下: "+ Arrays.asList(words));
        ProxyTest.invoke(StreamEnd.class,functionName);
    }
    /**
     * 获取流中元素的数量
     */
    public static void count() {
        Stream<String> stream = Stream.of(words);
        long count = stream.count();
        System.out.println("words 中的数量为："+count);
    }

    /**
     * 获取流排序后的最大值
     */
    public static void max() {
        Stream<String> stream = Stream.of(words);
        Optional<String> max = stream.max((o1,o2)->{
           return o1.length()-o2.length();
        });
        if(max.isPresent()){
            System.out.println("words 中长度最大的元素是： "+max);
        }
        else{
            System.out.println("words 中不存在最大元素");
        }
    }

    /**
     * 获取排序后的最小值
     */
    public static void min() {
        Stream<String> stream = Stream.of(words);
        Optional<String> min = stream.min((o1,o2)->{
            return o1.length()-o2.length();
        });
        if(min.isPresent()) {
            System.out.println("words 中长度最小的元素是："+min.get());
        }else{
            System.out.println("words中不存在最小元素");
        }

    }

    /**
     * 将流转换为具体的集合
     */
    public static void collect() {
        Stream<String> stream = Stream.of(words);
        //将流转换为List
        List<String> listResult = stream.collect(Collectors.toList());
        System.out.println("words 转为list : "+listResult);
        //将流转为Set
        Stream<String> stringStream = listResult.stream();
        Set<String> setResult = stringStream.collect(Collectors.toSet());
        System.out.println("words 转为Set: "+setResult);
        //将流转为Map k-字符串的值 v-字符串长度
        Stream<String> stringStream1 = setResult.stream();
        // 这里注意，如果发生k重复的情况下，流的转换是回报错的
        Map<String,Integer> map = stringStream1.collect(Collectors.toMap(s->{return s;},s->{return s.length();}));
        System.out.println("set 转为Map: "+map);
    }

    /**
     * 获取流中第一个元素
     */
    public static void findFirst() {
        Stream<String> stream = Stream.of(words);
        Optional<String> optional = stream.findFirst();
        if(optional.isPresent()) {
            System.out.println("words 中第一个元素是："+optional.get());
        }else {
            System.out.println("words 不存在第一个元素");
        }

    }

    /**
     * 随机获取流中一个元素
     */
    public static void findAny() {
        Stream<String> stream = Stream.of(words);
        Optional<String> optional = stream.findAny();
        if(optional.isPresent()) {
            System.out.println("words 随机获取一个元素："+optional.get());
        } else {
            System.out.println("words 中不存在元素");
        }

    }

    /**
     * 判断流中是否存在元素符合规则
     */
    public static void anyMatch() {
        Stream<String> stream = Stream.of(words);
        boolean lengthBigerThan4 = stream.anyMatch(s->{
            return s.length()>4;
        });
        System.out.println("words 是否存在长度大于4的元素："+lengthBigerThan4);

    }

    /**
     * 判断流中是否全部元素都符合规则
     */
    public static void allMatch() {
        Stream<String> stream = Stream.of(words);
        boolean allItemLengthBigerThan4 = stream.allMatch(s->{
            return s.length()>4;
        });
        System.out.println("words 中元素的长度都大于4："+allItemLengthBigerThan4);

    }

    /**
     * 判断流中是否全部元素都不符合规则
     */
    public static void nonMatch() {
        Stream<String> stream = Stream.of(words);
        boolean nonItemLengthBigerThan10 = stream.noneMatch(s->{
           return s.length() > 10;
        });
        System.out.println("words 中没有元素大于10 ："+nonItemLengthBigerThan10);

    }
}
